﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xyz.BusinessObjects;

using Xyz.DataObjects.Interfaces;

namespace Xyz.DataObjects.Entity.Dao
{
    public class EntityFlightDao : IFlightDao
    {
        public List<Airport> GetAirports()
        {
            using (var context = EntityObjectFactory.CreateContext())
            {
                var airports = new List<Airport>();
                var query = context.AirportEntities.AsQueryable().ToList();

                query.ForEach(x => airports.Add(Mapper.Map(x)));
                airports.Sort(CompareAirportName);

                return airports;
            }
        }

        public Flight GetFlightStatus(String flightCode, DateTime flightDate, String flightAirport, bool isArrival)
        {
            using (var context = EntityObjectFactory.CreateContext())
            {
                var flight = context.FlightEntities.SingleOrDefault(x => x.FlightCode == flightCode);

                if (flight != null)
                {
                    if (isArrival)
                    {
                        if (flight.ArrivalDateTime.ToShortDateString() == flightDate.ToShortDateString()
                           && flight.ArrivalAirport == flightAirport)
                            return (Mapper.Map(flight));
                    }
                    else
                    {
                        if (flight.DepartureDateTime.ToShortDateString() == flightDate.ToShortDateString()
                           && flight.DepartureAirport == flightAirport)
                            return (Mapper.Map(flight));
                    }
                }
            }

             return null;
        }

        private static int CompareAirportName(Airport airport1, Airport airport2) 
        {
            return airport1.AirportName.CompareTo(airport2.AirportName);
        }


        public Aircraft GetAircraftByFlightId(int flightId)
        {
            using (var context = EntityObjectFactory.CreateContext())
            {
                var flight = context.FlightEntities.SingleOrDefault(x => x.FlightId == flightId);

                if (flight != null)
                {
                    return (Mapper.Map(flight.Aircraft));
                }

                return null;
            }
        }

        public void InsertFlight(Flight flight)
        {
            var entity = Mapper.Map(flight);

            using (var context = EntityObjectFactory.CreateContext())
            {
                context.FlightEntities.AddObject(entity);
                context.SaveChanges();
            }
        }

        public List<Aircraft> GetAircrafts()
        {
            using (var context = EntityObjectFactory.CreateContext())
            {
                var aircrafts = new List<Aircraft>();
                var query = context.Aircrafts.AsQueryable().ToList();

                query.ForEach(x=> aircrafts.Add(Mapper.Map(x)));

                return aircrafts;
            }
        }

        public List<Terminal> GetTerminalByAirportId(string airportCode)
        {
            using (var context = EntityObjectFactory.CreateContext())
            {
                var terminals = new List<Terminal>();
                var query = context.TerminalEntities.Where(x => x.AirportCode == airportCode).AsQueryable().ToList();

                query.ForEach(x => terminals.Add(Mapper.Map(x)));

                return terminals;
            }
        }
        public List<Flight> GetFlights()
        {
            using (var context = EntityObjectFactory.CreateContext())
            {
                var flights = new List<Flight>();
                var query = context.FlightEntities.AsQueryable().ToList();

                query.ForEach(x => flights.Add(Mapper.Map(x)));
                flights.Sort(CompareFlightNumber);

                return flights;
            }
        }

        private static int CompareFlightNumber(Flight flight1, Flight flight2)
        {
            return flight1.FlightCode.CompareTo(flight2.FlightCode);
        }

        public Flight GetFlightByFlightId(int flightId)
        {
            using (var context = EntityObjectFactory.CreateContext())
            {
                var flight = context.FlightEntities.SingleOrDefault(x => x.FlightId == flightId);

                if (flight != null)
                    return Mapper.Map(flight);

                return null;
            }
        }

        public void UpdateFlight(Flight flight)
        {
            using (var context = EntityObjectFactory.CreateContext())
            {
                var query = context.FlightEntities.SingleOrDefault(x => x.FlightId == flight.FlightId);

                query.FlightCode = flight.FlightCode;
                query.AircraftId = flight.AircraftId;
                query.ArrivalAirport = flight.ArrivalAirport;
                query.ArrivalDateTime = flight.ArrivalDateTime;
                query.ArrivalTerminal = flight.ArrivalTerminal;
                query.DepartureAirport = flight.DepartureAirport;
                query.DepartureDateTime = flight.DepartureDateTime;
                query.DepartureTerminal = flight.DepartureTerminal;
                query.Distance = flight.Distance;
                query.TaxSurcharge = flight.TaxSurcharge;
                query.FlightStatus = flight.FlightStatus;

                context.SaveChanges();
            }
        }

        public void DeleteFlight(int flightId)
        {
            using (var context = EntityObjectFactory.CreateContext())
            {
                var query = context.FlightEntities.SingleOrDefault(x => x.FlightId == flightId);

                if (query != null)
                    context.FlightEntities.DeleteObject(query);
            }
        }

        public List<Flight> GetFlightsByFlightCode(string flightCode)
        {
            using (var context = EntityObjectFactory.CreateContext())
            {
                List<Flight> flights = new List<Flight>();
                var query = context.FlightEntities.Where(x => x.FlightCode == flightCode).AsQueryable().ToList();

                if (query != null)
                {
                    query.ForEach(x => flights.Add(Mapper.Map(x)));
                    return flights;
                }

                return null;
            }
        }

        public List<Flight> GetFlights(DateTime departureDate, String departureAirport, String arrivalAirport)
        {
            using (var context = EntityObjectFactory.CreateContext())
            {
                DateTime dayAfterDepature = departureDate.AddDays(1);

                var Flights = new List<Flight>();
                var query = context.FlightEntities.Where(
                                x => x.DepartureDateTime >= departureDate
                                     && x.DepartureDateTime < dayAfterDepature
                                     && x.DepartureAirport == departureAirport
                                     && x.ArrivalAirport == arrivalAirport).AsQueryable().ToList();

                query.ForEach(x => Flights.Add(Mapper.Map(x)));

                return Flights;
            }
        }
    }
}
